home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 332_01 / jotto.c < prev    next >
C/C++ Source or Header  |  1990-03-23  |  14KB  |  673 lines

  1. /*-                            -*- Fundamental -*-
  2.  *
  3.  *  Facility:            jotto(6)
  4.  *
  5.  *  File:            jotto.c
  6.  *
  7.  *  Associated files:        - [ none]
  8.  *
  9.  *  Description:        Plays the game of jotto
  10.  *
  11.  *  Notes:            No rules included.
  12.  *
  13.  *  Portability:        Edited to conform to X/Open Portability Guide,
  14.  *                ed. 3, 1988
  15.  *
  16.  *  Author:            David M. Fogg
  17.  *                2632 N.E. Fremont
  18.  *                Portland, OR 97212
  19.  *
  20.  *  Editor:            Anders Thulin
  21.  *                Rydsvagen 288
  22.  *                S-582 50 Linkoping
  23.  *                SWEDEN
  24.  *
  25.  *
  26.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  27.  *
  28.  *  Copyright (c) 1981 by David M. Fogg
  29.  *
  30.  *  Permission is herewith granted for noncommercial distribution
  31.  *  through the BDS User's Group; any and all forms of commercial
  32.  *  redistribution are strenuously unwished-for.
  33.  *
  34.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  35.  *
  36.  *  Edit history :
  37.  *
  38.  *  Vers  Ed   Date       By             Comments
  39.  *  ----  ---  ----------  ----------------  -------------------------------
  40.  *   1.0    0  1980-11-13  David M. Fogg     Creation day
  41.  *          1  1980-11-18  David M. Fogg     Creation ... finished
  42.  *          2  1980-11-10  David M. Fogg     Bugwork
  43.  *   1.1    3  1988-10-25  Anders Thulin     Many BDS-isms removed to make
  44.  *                         program K&R compatible. General
  45.  *                         cleanup for portability. Added
  46.  *                         some comments.
  47.  *                    
  48.  */
  49.  
  50. /* - - Configuration options: - - - - - - - - - - - - - - - - - - - - - - - */
  51.  
  52. /*
  53.  *    
  54.  *  The following environments are supported:
  55.  *
  56.  *    ANSI        ANSI C
  57.  *    BSD        Berkeley UNIX
  58.  *    SV2        AT&T UNIX System V.2
  59.  *    XPG3        X/Open Portability Guide, ed. 3
  60.  *    ZTC205        MS-DOS + Zortech C 2.05
  61.  *
  62.  *  If you have an ANSI C conforming compiler, define ANSI. Otherwise,
  63.  *  use the definition that best matches your environment.
  64.  *
  65.  */
  66.     
  67. #define    ANSI        0    /* 1 -> ANSI C, 0 -> K&R */
  68. #define    BSD        0
  69. #define    SV2        0
  70. #define    XPG2        0
  71. #define ZTC205        1
  72.  
  73. #if ANSI
  74. # include <ctype.h>
  75. # include <stdio.h>
  76. # include <stdlib.h>
  77. # include <string.h>
  78. # include <time.h>
  79. #endif
  80.  
  81. #if BSD
  82. # include <ctype.h>
  83. # include <stdio.h>
  84. # include <string.h>
  85.  typedef long  time_t;
  86.  extern void   exit();
  87.  extern int    rand();
  88.  extern void   srand();
  89.  extern time_t time();        
  90. #endif
  91.  
  92. #if SV2 
  93. # include <ctype.h>
  94. # include <stdio.h>
  95. # include <string.h>
  96.  typedef long  time_t;
  97.  extern void   exit();
  98.  extern int    rand();
  99.  extern void   srand();
  100.  extern time_t time();        
  101. #endif
  102.  
  103. #if XPG3
  104. # include <ctype.h>
  105. # include <stdio.h>
  106. # include <string.h>
  107.  typedef long  time_t;    /*[???] or should it be time_t from <sys/types.h> ? */
  108.  extern void   exit();
  109.  extern int    rand();
  110.  extern void   srand();
  111.  extern time_t time();    
  112. #endif
  113.  
  114. #if ZTC205
  115. # include <ctype.h>
  116. # include <stdio.h>
  117. # include <string.h>
  118.  typedef long  time_t;
  119.  extern void   exit();
  120.  extern int    rand();
  121.  extern void   srand();
  122.  extern time_t time();    
  123. #endif
  124.  
  125. # include <curses.h>
  126.  
  127. /*
  128.  *  Tweakables:
  129.  *
  130.  *  The reason ALPHA_SIZE has been declared as a macro is that some
  131.  *  compilers handle sizeof("<string>") as a synonym to sizeof(char *),
  132.  *  which is wrong.  ALPHA_SIZE should be defined to be the number
  133.  *  of characters in the string ALPHABET.
  134.  *
  135.  */
  136.  
  137. #define WORD_FILE    "jotto.wds"    /* default word file */
  138. #define MAXWORDS      600        /* max nr of words in word file */
  139.  
  140. #define    ALPHABET    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  141. #define    ALPHA_SIZE    26
  142.  
  143. /* Code for RETURN/ENTER key -- some systems use \r, some \n */
  144.  
  145. #define RETURN        '\n'
  146.  
  147. /*
  148.  *  Non-tweakables:
  149.  *
  150.  */
  151.  
  152. #ifndef TRUE
  153. # define    TRUE    1
  154. # define    FALSE    0
  155. #endif
  156.  
  157. #define LETS      5    /* letters/word */
  158. #define ISCORE      21    /* initial score */
  159.  
  160. /* screen layout parameters */
  161.  
  162. #define XTITLE      40    /* Title loc */
  163. #define YTITLE      1
  164. #define XPROMPT   33    /* prompt loc */
  165. #define YPROMPT   4
  166. #define XSCORE      3    /* score col */
  167. #define XGUESS      10    /* guess col */
  168. #define XMATCH      17    /* match col */
  169. #define XSTATE      20    /* status col */
  170. #define YHEAD      0    /* header row */
  171. #define YFIRST      2    /* first guess row */
  172. #define XLABELS   33    /* list labels col */
  173. #define XLISTS      42    /* lists cols */
  174. #define YYES      6    /* confirmed letters row */
  175. #define YNO      8    /* eliminated letters row */
  176. #define YPOSS      10    /* possible letters row */
  177. #define XINST      30    /* instructions loc */
  178. #define YINST      13
  179.  
  180. /*
  181.  *  Global variables
  182.  *
  183.  */
  184.  
  185. static int  wordok, giveup;
  186. static int  score;
  187. static char word[LETS+3];
  188. static char guess[LETS+1], gots[LETS+1];
  189. static int  count;
  190. static char guesslis[ISCORE+1][LETS+1];
  191. static int  changed;
  192.  
  193. static char nots[ALPHA_SIZE],
  194.             maybes[ALPHA_SIZE];
  195.  
  196. static char alphabet[] = ALPHABET;
  197.  
  198. /*
  199.  *  Local functions:
  200.  *
  201.  */
  202.  
  203. #ifdef __STDC__
  204.  static void dochange(void);
  205.  static void doguess(void);
  206.  static void doscreen(void);
  207.  static void dostate(int s);
  208.  static int  getlet(void);
  209.  static void getword(char *wd);
  210.  static int  inset(char *string, int ch);
  211.  static void inword(int x, int y, char *p, char *w);
  212.  static void modgot (int old, int new);
  213.  static int  nomore(void);
  214.  static void printset(char *s);
  215.  static void xfer (int l, char *src, char *dest);
  216. #else
  217.  static void dochange();
  218.  static void doguess();
  219.  static void doscreen();
  220.  static void dostate();
  221.  static int  getlet();
  222.  static void getword();
  223.  static int  inset();
  224.  static void inword();
  225.  static void modgot ();
  226.  static void printset();
  227.  static int  nomore();
  228.  static void xfer ();
  229. #endif
  230.  
  231. /*
  232.  *  Routine:        dochange
  233.  *
  234.  *  Description:    Read change commands from the terminal and
  235.  *            perform the changes.
  236.  *
  237.  */
  238.  
  239. static void dochange ()
  240. {
  241.    int  ch;
  242.    int sc;
  243.    char let;
  244.    static char legals[] = {'A', '+', '=', '_', 'N', '+', RETURN, '\0'};
  245.  
  246.    changed = 0;
  247.    wordok = FALSE;
  248.  
  249.    mvaddstr(YPROMPT, XPROMPT, "Change: "); refresh();
  250.    do {
  251.      if (islower(ch = getch())) {
  252.        ch = toupper(ch);
  253.      }    
  254.    } while (inset(legals, ch) == 0);
  255.    refresh();
  256.    if (ch == 'A')
  257.       return;
  258.    else
  259.       wordok = TRUE;
  260.  
  261.    while (ch != RETURN && changed < LETS) {
  262.       ++changed;
  263.       switch (ch) {
  264.      case '=': ch = '+'; break;
  265.      case '_': ch = '-';
  266.       }
  267.       addch(ch);
  268.       let = getlet(); addch(' ');
  269.       switch (ch) {
  270.      case '+': modgot(' ', let);        break;
  271.      case '-': modgot(let, ' ');        break;
  272.      case 'N': xfer(let, maybes, nots); break;
  273.      case 'M': xfer(let, nots, maybes); break;
  274.       }
  275.       refresh();
  276.       do {
  277.      ch = toupper(getch());
  278.       } while (inset(legals, ch) == 0);
  279.       refresh();
  280.    }
  281.    if (changed > 0) {
  282.       move(YPROMPT, XPROMPT); clrtoeol();
  283.       move(YYES, XLISTS); addstr(gots);
  284.       move(YNO, XLISTS); printset(nots);
  285.       move(YPOSS, XLISTS); printset(maybes);
  286.       for (sc = ISCORE; sc >= score ; --sc) dostate(sc);
  287.       dochange();
  288.    }
  289. }
  290.  
  291. /*
  292.  *  Routine:        doguess
  293.  *
  294.  *  Description:    Input guess from user and process it.
  295.  *
  296.  */
  297.  
  298. static void doguess ()    
  299. {
  300.   int i, j, y;
  301.   char str[LETS+1];
  302.  
  303.   /*  1.  Get guess from user:  */
  304.  
  305.   y = YFIRST + ISCORE - score;
  306.   move(y, XSCORE); printw("%4d", score);
  307.   inword(XGUESS-1, y, " ", guess);
  308.  
  309.   /*  2.  Process guess:  */
  310.  
  311.   if (strcmp(guess, "?????") == 0) {
  312.     giveup = TRUE;
  313.   } else {
  314.     giveup = FALSE;
  315.     strcpy(str, word); count = 0;
  316.     for (i = 0; i < LETS; ++i) {
  317.       if ((j = inset(str, guess[i])) > 0) {
  318.         ++count;
  319.         str[j-1] = tolower(str[j-1]);
  320.       }
  321.     }
  322.     printw("%3d", count);
  323.     strcpy(guesslis[score], guess);
  324.     dostate(score);
  325.  }
  326. }
  327.  
  328. /*
  329.  *  Routine:        doscreen
  330.  *
  331.  *  Description:    Clears the screen. Prints guess columns, some
  332.  *            help text and various other stuff.
  333.  *
  334.  */
  335.  
  336. static void doscreen()
  337. {
  338.   clear();
  339.  
  340.   mvaddstr(YTITLE, XTITLE, "--> J O T T O  <--");
  341.  
  342.   mvaddstr(YHEAD,   XSCORE, "Score  Guess  #  STATE");
  343.   mvaddstr(YHEAD+1, XSCORE, "=====  =====  =  =====");
  344.  
  345.   move(YYES, XLABELS+3);  addstr("YES:");
  346.  
  347.   move(YNO, XLABELS+4);   addstr("NO:");
  348.  
  349.   move(YPOSS, XLABELS+1); addstr("MAYBE:");
  350.   move(YPOSS, XLISTS);    printset(maybes);
  351.  
  352.